<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
</head>
<style type="text/css">       
	html,body
	{
        margin: 0;           
	    padding: 0;
        border:0px;
        overflow-y: hidden;
        overflow-x: hidden;}
</style>
<body>
    <div id="container" style="width:100%;height:100vh;border:0px;"></div>
    <script src="./monaco-editor/dev/vs/loader.js"></script>
    <script>

        var editor;

        // import * as monaco from 'monaco-editor/esm/vs/editor/editor.api.js';
        require.config({ paths: { 'vs': './monaco-editor/dev/vs' }});
        require(['vs/editor/editor.main'], function() 
        {
            // Register a new language
            monaco.languages.register({ id: 'mySpecialLanguage' });

            // Register a tokens provider for the language
            monaco.languages.setMonarchTokensProvider('mySpecialLanguage', {
            tokenizer: {
                root: [
                    [/\[error.*/, "custom-error"],
                    [/\[notice.*/, "custom-notice"],
                    [/\[info.*/, "custom-info"],
                    /*[/\[[a-zA-Z 0-9:]+\]/, "custom-date"]*/
                    [/\[[0-9- 0-9:]+\]/, "custom-date"],
                    [/\[command.*/, "custom-command"],
                    [/\[compile.*/, "custom-compile"],
                    [/\[upload.*/, "custom-upload"],
                ]
            }
        });

        // Define a new theme that contains only rules that match this language
        monaco.editor.defineTheme('myCoolTheme', 
        {
            base: 'vs-dark',
            //base: 'vs',
            inherit: false,
            rules: [
                { token: 'custom-info', foreground: '#808080' },
                { token: 'custom-error', foreground: '#FF0000', fontStyle: 'bold' },
                { token: 'custom-notice', foreground: '#FFFFFF' , fontStyle: 'bold' },
                { token: 'custom-date', foreground: '#008800' },
                { token: 'custom-command', foreground: '#FF9900', fontStyle: 'bold' },
                { token: 'custom-compile', foreground: '#66CCFF' },
                { token: 'custom-upload', foreground: '#FFCC66' }
            ],
            colors: 
            {
                'editor.background': '#1F1F1F',
                //'editor.foreground': '#000000',
                //'editor.background': '#EDF9FA',
                'editorCursor.foreground': '#8B0000',
                'button.background':'#FF0000',
                'editor.lineHighlightBackground': '#0000FF20',
                //'editorLineNumber.foreground': '#008800',
                'editor.selectionBackground': '#88000030',
                'editor.inactiveSelectionBackground': '#88000015'
            }
        });

        // Register a completion item provider for the new language
        monaco.languages.registerCompletionItemProvider('mySpecialLanguage', {
            provideCompletionItems: () => {
                var suggestions = [
                {
                    label: 'simpleText',
                    kind: monaco.languages.CompletionItemKind.Text,
                    insertText: 'simpleText'
                }, 
                {
                    label: 'testing',
                    kind: monaco.languages.CompletionItemKind.Keyword,
                    insertText: 'testing(${1:condition})',
                    insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet
                }, 
                {
                    label: 'ifelse',
                    kind: monaco.languages.CompletionItemKind.Snippet,
                    insertText: [
                        'if (${1:condition}) {',
                        '\t$0',
                        '} else {',
                        '\t',
                        '}'
                    ].join('\n'),
                    insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
                    documentation: 'If-Else Statement'
                }];
                return { suggestions: suggestions };
            }
        });

        // Through the options literal, the behaviour of the editor can be easily customized.
        // Here are a few examples of config options that can be passed to the editor.
        // You can also call editor.updateOptions at any time to change the options.
        editor = monaco.editor.create(document.getElementById("container"), 
        {
            theme: 'myCoolTheme',
            /*value: "getCode()",*/
            value: " ",
            language: 'mySpecialLanguage',
            fontSize: 18,
            automaticLayout:true,
            verticalHasArrows: true,
            /*horizontalHasArrows: true,*/
            vertical: 'auto',
            horizontal: 'hidden',
            roundedSelection: false,
            scrollBeyondLastLine: false,
            readOnly: false, // 默认情况下不可编辑
            minimap: 
            {
                enabled: false,
            }
        });

        function getCode() 
        {
            return [
                '[Sun Mar 7 16:02:00 2004] [notice] Apache/1.3.29 (Unix) configured -- resuming normal operations',
                '[Sun Mar 7 16:02:00 2004] [info] Server built: Feb 27 2004 13:56:37',
                '[Sun Mar 7 16:02:00 2004] [notice] Accept mutex: sysvsem (Default: sysvsem)',
                '[Sun Mar 7 16:05:49 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed',
                '[Sun Mar 7 16:45:56 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed',
                '[Sun Mar 7 17:13:50 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed',
                '[Sun Mar 7 17:21:44 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed',
                '[Sun Mar 7 17:23:53 2004] statistics: Use of uninitialized value in concatenation (.) or string at /home/httpd/twiki/lib/TWiki.pm line 528.',
                '[Sun Mar 7 17:23:53 2004] statistics: Can\'t create file /home/httpd/twiki/data/Main/WebStatistics.txt - Permission denied',
                '[Sun Mar 7 17:27:37 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed',
                '[Sun Mar 7 17:31:39 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed',
                '<11>httpd[31628]: [error] [client xx.xx.xx.xx] File does not exist: /usr/local/installed/apache/htdocs/squirrelmail/_vti_inf.html in 29-Mar 15:18:20.50 from xx.xx.xx.xx',
                '<11>httpd[25859]: [error] [client xx.xx.xx.xx] File does not exist: /usr/local/installed/apache/htdocs/squirrelmail/_vti_bin/shtml.exe/_vti_rpc in 29-Mar 15:18:20.54 from xx.xx.xx.xx',
            ].join('\n');;
        }
        });

        function clear()
        {
            editor.setValue(" ");
        }

        function setEditable(isEditable)
        {
            if(isEditable == true)
            {
                editor.updateOptions({readOnly: false});
            }
            else
            {
                editor.updateOptions({readOnly: true});
            }
        }

        function addCode(txt)
        {
            const lineCount = editor.getModel().getLineCount();
            const lastLineLength = editor.getModel().getLineMaxColumn(lineCount);

            const range = new monaco.Range(
                lineCount,
                lastLineLength,
                lineCount,
                lastLineLength
            );

            editor.executeEdits('', [
                { range: range, text: txt }
            ])
        }
        </script>
    </body>
</html>